package com.flying.rsocket;

import io.rsocket.transport.netty.client.TcpClientTransport;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.reactivestreams.Publisher;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.time.Instant;

@SpringBootApplication
public class RSocketConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RSocketConsumerApplication.class, args);
    }

    @Bean
    RSocketRequester requester(RSocketRequester.Builder builder) {
        return builder.connect(TcpClientTransport.create(7000))
                .block();
    }

}


@RestController
class GreetingsRestController {
    private final RSocketRequester requester;

    public GreetingsRestController(RSocketRequester requester) {
        this.requester = requester;
    }

    @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/greet/sse/{name}")
    Publisher<GreetingResponse> greetStream(@PathVariable String name) {
        return this.requester.route("greet-stream")
                .data(new GreetingRequest(name))
                .retrieveFlux(GreetingResponse.class);
    }

    @GetMapping("/greet/{name}")
    Publisher<GreetingResponse> greet(@PathVariable String name) {
        return this.requester.route("greet")
                .data(new GreetingRequest(name))
                .retrieveMono(GreetingResponse.class);

    }

    @GetMapping("/error")
    Publisher<GreetingResponse> error() {
        return this.requester.route("error")
                .retrieveFlux(GreetingResponse.class);
    }

}


@Data
@AllArgsConstructor
@NoArgsConstructor
class GreetingRequest {
    private String name;
}

@Data
class GreetingResponse {
    private String greeting;

    GreetingResponse() {
    }

    GreetingResponse(String name) {
        this.withGreeting("Hello" + name + " @ " + Instant.now());
    }


    GreetingResponse withGreeting(String msg) {
        this.greeting = msg;
        return this;
    }
}